<?php


namespace library\request;

/**
 * klasa do przetwarzania żądań HTTP na adresy URL
 *
 * @author Damian Jóźwiak
 */
class Request extends \library\Base{
    protected $request;
    /**
     * @readwrite
     */
    public $willFollow = true;
    /**
     * @readwrite
     */
    protected $headers = array();
    /**
     * @readwrite
     */
    protected $options=array();
    /**
     * @readwrite
     */
    protected $referer;
    /**
     * @readwrite
     */
    protected $agent;
    public function __construct($options = array()) {
        parent::__construct($options);
        $this->setAgent(\library\RequestMethods::server("HTTP_USER_AGENT", "Curl/PHP ".PHP_VERSION));
    }
    function get($url,$parameters=array()){
        if (!empty($parameters)){
            $url.= \library\StringMethods::indexOf($url, "?")? "&":"?";
            $url.= (is_string($parameters))? $parameters: http_build_query($parameters,"","&");
        }
        return $this->request("GET", $url);
    }
     function head($url,$parameters=array()){
       return $this->request("HEAD", $url,$parameters);
    }
    function post($url,$parameters=array()){
       return $this->request("POST", $url, $parameters );
    }
    function put($url,$parameters=array()){
       return $this->request("PUT", $url, $parameters);
    }
    public function request($method,$url,$parameters=array()){
        $request = $this->request=  curl_init();
        if (is_array($parameters)){
            $parameters = http_build_query($parameters,"","&");
        }
        $this->setRequestMethod($method)->setRequestOptions($url,$parameters)->setRequestHeaders();
        $response = curl_exec($request);
        if ($response){
            $response = new Response(array("response"=>$response));
            curl_close($request);
        }
        else{
            curl_close($request);
            throw new ResponseException(curl_errno($request)." - ".curl_error($request));
        }
        return $response;
        
    }
    protected function setOption($key,$value){
     curl_setopt($this->request, $key, $value);
     return $this;
    }
    protected function normalize($key){
        return "CURLOPT_".str_replace("CURLOPT_", "", strtoupper($key));
    }
    protected function setRequestMethod($method){
        switch (strtoupper($method)){
            case "HEAD":
                $this->setOption(CURLOPT_NOBODY, true);
                break;
            case "GET":
                $this->setOption(CURLOPT_HTTPGET, true);
                break;
            case "POST":
                $this->setOption(CURLOPT_POST, true);
                break;
            default :
                $this->setOption(CURLOPT_CUSTOMREQUEST,$method);
                break;
        }
        return $this;
    }
    protected function setRequestOptions($url,$parametrs){
        $this->setOption(CURLOPT_URL, $url)->setOption(CURLOPT_HEADER, true)->setOption(CURLOPT_RETURNTRANSFER, true)
                ->setOption(CURLOPT_USERAGENT, $this->agent);
        if (!empty($parametrs)){
            $this->setOption(CURLOPT_POSTFIELDS, $parametrs);
        }
        if($this->getWillFollow()){
            $this->setOption(CURLOPT_FOLLOWLOCATION, true);
        }
        if($this->getReferer()){
            $this->setOption(CURLOPT_REFERER, $this->getReferer());
        }
        foreach ($this->options as $key=>$value){
            $this->setOption(constant($this->normalize($key)), $value);
        }
        return $this;
    }
    protected function setRequestHeaders(){
        $headers=array();
        foreach($this->headers as $key =>$value){
            $headers[]=$key.": ".$value;
        }
        $this->setOption(CURLOPT_HTTPHEADER, $headers);
        return $this;
    }
}
